Skip to content

feat(appkit): split the agents plugin into focused modules (#532) - #547

Merged
MarioCadenas merged 9 commits into
mainfrom
refactor/agents-plugin
Aug 31, 2026
Merged

feat(appkit): split the agents plugin into focused modules (#532)#547
MarioCadenas merged 9 commits into
mainfrom
refactor/agents-plugin

Conversation

@MarioCadenas

@MarioCadenas MarioCadenas commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

Behavior-preserving refactor of the ~2,500-line agents.ts god-file into focused modules. Stacked on #543 (it only touches agents.ts, which #543 owns) — independent of #544.

No behavior changes: every commit keeps pnpm --filter=@databricks/appkit typecheck and the agent test suite (394 tests) green.

agents.ts: 2,512 → 1,784 lines (−728, ~29%). The plugin is now an orchestrator (registry wiring + route handlers + SSE plumbing) delegating cohesive concerns to focused sibling modules.

What moved

  • Pure helpersapproval.ts, prompt.ts, builtin-tools.ts, adapter-extensions.ts.
  • Skill loading/dispatchskill-loader.ts (discovery, catalog resolution, load_skill/read_skill_file).
  • Registry assemblyregistry.ts (loadCodeAgents, hasCodeAgentSources, resolveDefaultAgent, AgentSource).
  • Tool-dispatch enginetool-dispatch.ts (RunState + dispatchToolCall + runSubAgent) as free functions over a ToolDispatchDeps object.
  • Config resolutionresolve-config.ts (resolveApprovalPolicy / resolveLimits pure fns; getters keep the memo cache).
  • Stream trackingActiveStreamTracker (active-stream map + per-user O(1) concurrency counter). Named to avoid clashing with the unrelated SSE-layer StreamRegistry in src/stream/.

Notes

  • Delegator pattern keeps call sites stable throughout; skillWorkspaceClient() stays as the OBO credential seam.
  • Deliberately not extracted: buildToolIndex (owns the mutable mcpClient lifecycle) and the HTTP handlers (the Plugin route contract) — both need 5-8 pieces of plugin state, so extraction would widen interfaces more than it'd clarify (fails the deep-module test). The remaining ~1,784 lines are the plugin genuinely being a plugin.
  • The agents-plugin concurrency tracker is intentionally separate from the SSE StreamRegistry: that one is a global, transport-level store (event replay buffers, global cap) with no per-user dimension; this one counts streams per user for maxConcurrentStreamsPerUser + ownership checks.
  • Tests updated where they white-boxed moved internals (dispatch-tool-call, dos-limits, approval-route).

Merge order

Stacked on #543; auto-retargets to main once #543 merges. Merge after #543.

@MarioCadenas
MarioCadenas requested a review from a team as a code owner August 21, 2026 15:13
@MarioCadenas
MarioCadenas requested review from ditadi and removed request for a team August 21, 2026 15:13
@MarioCadenas MarioCadenas changed the title refactor(appkit): split the agents plugin into focused modules (stacked on #543) feat(appkit): Agent Skills v1 (SKILL.md progressive disclosure) + agents plugin refactor (#532) Aug 21, 2026
@MarioCadenas
MarioCadenas changed the base branch from split/532/sdk-feature to main August 21, 2026 17:02
@MarioCadenas MarioCadenas changed the title feat(appkit): Agent Skills v1 (SKILL.md progressive disclosure) + agents plugin refactor (#532) refactor(appkit): split the agents plugin into focused modules (#532) Aug 21, 2026
@MarioCadenas
MarioCadenas changed the base branch from main to split/532/fixtures-docs August 21, 2026 17:11
@MarioCadenas
MarioCadenas force-pushed the refactor/agents-plugin branch from 9831cec to a8f7cba Compare August 21, 2026 17:15
Base automatically changed from split/532/fixtures-docs to main August 31, 2026 09:35
Comment thread packages/appkit/src/plugins/agents/skill-loader.ts

@atilafassina atilafassina left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks like this PR adds new behavior. I think you should consider changing from refactor to feat

@MarioCadenas
MarioCadenas force-pushed the refactor/agents-plugin branch from a8f7cba to be33197 Compare August 31, 2026 10:05
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle size report

Compared against bundle-size-baseline.json (main).

@databricks/appkit

npm tarball (packed): 1.0 MB (+5.3 KB) — gzipped download (dist + bin; excludes release-only docs/NOTICE).

dist raw gzip
JS (runtime) 1.0 MB (+6.3 KB) 376 KB (+4.8 KB)
Type declarations 385 KB (-3.2 KB) 136 KB (-1.1 KB)
Source maps 2.1 MB (+10 KB) 704 KB (+7.7 KB)
Other 11 KB 3.7 KB
Total 3.5 MB (+13 KB) 1.2 MB (+11 KB)
Per-entry composition (own code — deps external (as shipped))
Entry Initial (gz) Lazy (gz) Total (gz) node_modules (min) Own code (min)
. 95 KB 2.5 KB 97 KB external 311 KB
./beta 75 KB (+344 B) 456 B 75 KB (+344 B) external 225 KB (+956 B)
./testing 17 KB 0 B 17 KB external 50 KB
./tsdown 520 B 0 B 520 B external 813 B
./type-generator 22 KB 0 B 22 KB external 65 KB

Chunks:

Entry Chunk Load Size (gz)
. index.js initial 91 KB
. utils.js initial 4.0 KB
. remote-tunnel-manager.js lazy 2.5 KB
./beta beta.js initial 59 KB
./beta stream-manager.js initial 5.8 KB
./beta wide-event-emitter.js initial 3.2 KB
./beta databricks.js initial 3.0 KB
./beta configuration.js initial 2.1 KB
./beta service-context.js initial 1.3 KB
./beta client.js initial 434 B
./beta client-options.js initial 219 B
./beta supervisor-api.js lazy 192 B
./beta databricks.js lazy 141 B
./beta index.js lazy 123 B
./testing index.js initial 17 KB
./tsdown index.js initial 520 B
./type-generator index.js initial 22 KB

@databricks/appkit-ui

npm tarball (packed): 350 KB — gzipped download (dist + bin; excludes release-only docs/NOTICE).

dist raw gzip
JS (runtime) 395 KB 132 KB
Type declarations 229 KB 84 KB
Source maps 766 KB 253 KB
CSS 16 KB 3.2 KB
Total 1.4 MB 473 KB
Per-entry composition (consumer bundle — deps bundled, peerDeps external)
Entry Initial (gz) Lazy (gz) Total (gz) node_modules (min) Own code (min)
./js 5.3 KB 49 KB 55 KB 208 KB 14 KB
./js/beta 20 B 0 B 20 B 0 B 0 B
./react 432 KB 49 KB 481 KB 1.3 MB 177 KB
./react/beta 1.0 KB 0 B 1.0 KB 0 B 1.9 KB

Chunks:

Entry Chunk Load Size (gz)
./js index.js initial 5.2 KB
./js chunk initial 120 B
./js apache-arrow lazy 49 KB
./js/beta beta.js initial 20 B
./react index.js initial 430 KB
./react tslib initial 2.1 KB
./react apache-arrow lazy 49 KB
./react/beta beta.js initial 1.0 KB

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

🤖 AppKit PR bot

🔬 Run evals

Start an eval for this PR from the evals-monitor app: Go to Evals Monitor →

📦 Try this PR's app template

Scaffolds a new app from this PR's SDK build. Run it in any folder (requires the GitHub CLI — gh auth login — and the Databricks CLI):

gh run download 33384298640 -R databricks/appkit -n appkit-template-0.68.0-pr.ae5d702-refactor-agents-plugin-547 -D appkit-pr-547 \
  && unzip -o "appkit-pr-547/appkit-template-0.68.0-pr.ae5d702-refactor-agents-plugin-547.zip" -d "appkit-pr-547" \
  && databricks apps init --template "appkit-pr-547"

The template pins @databricks/appkit and @databricks/appkit-ui to tarballs built from this branch, so the scaffolded app runs against this PR's code.

…ules

Step 1 of splitting the ~2.5k-line agents plugin. Moves module-scope pure
functions/constants out of agents.ts verbatim (behavior-preserving):
- approval.ts            requiresApproval
- prompt.ts              composePromptForAgent
- builtin-tools.ts       LOAD_SKILL_TOOL_DEF, READ_SKILL_FILE_TOOL_DEF
- adapter-extensions.ts  buildAdapterExtensions, supervisorToolDescription, warnOnCapabilityMismatch

agents.ts: 2512 -> 2331 lines. typecheck + 394 agent tests green.

Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
…ader

Step 2 of splitting the agents plugin. Moves skill discovery, per-agent
catalog resolution, and the load_skill/read_skill_file dispatch into
skill-loader.ts as free functions; the class keeps thin delegators (call sites
unchanged) and skillWorkspaceClient() as the OBO credential seam.

agents.ts: 2331 -> 2152 lines. typecheck + 394 agent tests green.

Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
Step 3 of splitting the agents plugin. Moves the decoupled boot-time
assembly helpers into registry.ts: loadCodeAgents, hasCodeAgentSources (now
internal), resolveDefaultAgent, and the AgentSource type. buildAgentRegistry
stays as the orchestrator that wires them. Also merges a duplicate import in
skill-loader.ts.

agents.ts: 2152 -> 2088 lines. typecheck + 394 agent tests green.

Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
…tch.ts

Step 4 (final) of splitting the agents plugin. Moves dispatchToolCall +
runSubAgent — the tool-call budget, approval gate, and sub-agent recursion —
into tool-dispatch.ts as free functions over RunState + a ToolDispatchDeps
object. The plugin builds deps via toolDispatchDeps(); the two executeTool
closures call the free function. RunState moves with them. Tests updated to
invoke the free functions (deps built from the plugin's own builder).

agents.ts: 2088 -> 1839 lines (2512 -> 1839 across all four steps). typecheck +
394 agent tests green.

Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
…g.ts

Moves resolvedApprovalPolicy / resolvedLimits defaulting into pure functions
over AgentsPluginConfig. The getters keep the approval-policy memo cache and
delegate. Config-only interface; both now unit-testable in isolation.

agents.ts: 1839 -> 1812 lines. typecheck + agent tests green.

Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
Moves the active-stream map + per-user counter (the O(1) concurrency-limit
check) into a StreamRegistry class. The plugin holds one instance and keeps
trackStream/untrackStream/countUserStreams as delegators; cancel/approve read
via streams.get(). Tests inject via trackStream and assert via the registry.

agents.ts: 1812 -> 1784 lines. typecheck + 394 agent tests green.

Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
The previous commit named it StreamRegistry, colliding with the existing
SSE-layer StreamRegistry in src/stream/ (connection/event-buffer tracking used
by StreamManager). They're different concepts; renamed the agents-plugin one to
ActiveStreamTracker (tracks active streams + per-user counts for the O(1)
concurrency limit) to avoid the name clash.

Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
…ing)

The prior commit's git add hit the already-deleted stream-registry.ts path,
aborted, and recorded only the deletion — leaving the pushed tip non-compiling
(agents.ts imported the removed file; active-stream-tracker.ts was uncommitted).
This adds the new module and the agents.ts import/usage so the tree builds.

Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
@MarioCadenas
MarioCadenas force-pushed the refactor/agents-plugin branch from 0a37f9f to 49c18cb Compare August 31, 2026 10:42
Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
@MarioCadenas
MarioCadenas enabled auto-merge (squash) August 31, 2026 10:52
@MarioCadenas MarioCadenas changed the title refactor(appkit): split the agents plugin into focused modules (#532) feat(appkit): split the agents plugin into focused modules (#532) Aug 31, 2026
@MarioCadenas
MarioCadenas merged commit 2329476 into main Aug 31, 2026
12 checks passed
@MarioCadenas
MarioCadenas deleted the refactor/agents-plugin branch August 31, 2026 10:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants